/***
 * @Description: 本文件是包含socket结构内部实现包括socket表结构的C语言文件
 * @Author: Liverpool
 * @Date: 2024-09-17 23:33:58
 * @LastEditTime: 2024-09-17 23:34:22
 * @LastEditors: Liverpool
 */
#include "sock.h"
#include "socket.h"
#include "raw.h"
// 变量定义区
#define SOCKET_AMX_NUM (RAW_MAX_NUM)
static x_socket_t socket_tbl[SOCKET_AMX_NUM];

/***
 * @description: (静态函数)返回socket结构在表中的索引
 * @Author: Liverpool
 * @Date: 2024-09-18 00:10:44
 * @return {*} socket表中的索引
 * @param {x_socket_t} *s 需要计算索引的socket表项
 */
static int get_index(x_socket_t *s)
{
    return (int)(s - socket_tbl);
}

/***
 * @description: (静态函数)计算得到表中索引的socket结构地址
 * @Author: Liverpool
 * @Date: 2024-09-18 00:13:27
 * @return {*} socket结构地址
 * @param {int} index socketa表中的索引
 */
static x_socket_t *get_socket(int index)
{
    if (index < 0 || index >= SOCKET_AMX_NUM)
        return (x_socket_t *)0;
    return socket_tbl + index;
}

/***
 * @description: (静态函数)socket表结构的分配
 * @Author: Liverpool
 * @Date: 2024-09-18 00:03:46
 * @return {*} 返回空余的socket表结构中的空余socket
 */
static x_socket_t *socket_alloc(void)
{
    x_socket_t *s = (x_socket_t *)0;
    for (int i = 0; i < SOCKET_AMX_NUM; i++)
    {
        x_socket_t *curr = socket_tbl + i;
        if (curr->state == SOCKET_STATE_FREE)
        {
            curr->state = SOCKET_STATE_USED;
            s = curr;
            break;
        }
    }
    return (x_socket_t *)s;
}

/****
 * @description: (静态函数)socket表结构中的socket进行释放
 * @Author: Liverpool
 * @Date: 2024-09-18 00:08:35
 * @return {*}
 * @param {x_socket_t} *s
 */
static void socket_free(x_socket_t *s)
{
    s->state = SOCKET_STATE_FREE;
}

/***
 * @description: socket表结构的初始化
 * @Author: Liverpool
 * @Date: 2024-09-17 23:39:25
 * @return {*} 初始化过程中出现的错误
 */
net_err_t socket_init(void)
{
    plat_memset(socket_tbl, 0, sizeof(x_socket_t));
    return NET_ERR_OK;
}

/***
 * @description: sock结构内部数据结构体初始化
 * @Author: Liverpool
 * @Date: 2024-09-22 23:30:27
 * @return {*}
 * @param {D_Sock} *sock
 * @param {int} family
 * @param {int} protocol
 * @param {D_Sock_Operation} *ops
 */
net_err_t sock_init(D_Sock *sock, int family, int protocol, const D_Sock_Operation *ops)
{
    sock->family = family;
    sock->protocol = protocol;
    sock->operation = ops;

    ip_addr_set_any(&sock->local_ip);
    ip_addr_set_any(&sock->remote_ip);
    sock->local_port = 0;
    sock->remote_port = 0;
    sock->error = NET_ERR_OK;
    sock->receive_tms = 0;
    sock->send_tms = 0;

    sock->recv_wait = (D_Sock_Wait *)0;
    sock->send_wait = (D_Sock_Wait *)0;
    sock->conn_wait = (D_Sock_Wait *)0;
    list_node_init(&sock->node);
    return NET_ERR_OK;
}

/***
 * @description: sock结构的内部释放
 * @Author: Liverpool
 * @Date: 2024-10-07 22:24:37
 * @return {*}
 * @param {D_Sock} *sock 需要释放发sock的内存地址
 */
void sock_uninit(D_Sock *sock)
{
    if (sock->recv_wait)
    {
        sock_wait_destroy(sock->recv_wait);
    }
    if (sock->send_wait)
    {
        sock_wait_destroy(sock->send_wait);
    }
    if (sock->conn_wait)
    {
        sock_wait_destroy(sock->conn_wait);
    }
}

/***
 * @description: sock等待结构体的初始化
 * @Author: Liverpool
 * @Date: 2024-10-05 00:15:37
 * @return {*} sock等待结构体的初始化过程中出现的错误
 * @param {D_Sock_Wait} *sock_wait 等待结构体的内存地址
 */
net_err_t sock_wait_init(D_Sock_Wait *sock_wait)
{
    sock_wait->err = NET_ERR_OK;
    sock_wait->waiting = 0;
    sock_wait->sem = sys_sem_create(0);
    return sock_wait->sem == SYS_SEM_INVALID ? NET_ERR_SYS : NET_ERR_OK;
}

/***
 * @description: 等待结构的销毁
 * @Author: Liverpool
 * @Date: 2024-10-05 16:02:11
 * @return {*}
 * @param {D_Sock_Wait} *sock_wait 等待结构的内存地址
 */
void sock_wait_destroy(D_Sock_Wait *sock_wait)
{
    // 释放信号量
    if (sock_wait->sem != SYS_SEM_INVALID)
    {
        sys_sem_free(sock_wait->sem);
    }
}

/***
 * @description: 等待结构的添加
 * @Author: Liverpool
 * @Date: 2024-10-05 16:03:39
 * @return {*}
 * @param {D_Sock_Wait} *sock_wait 等待结构的内存地址
 * @param {int} ms 需要等待的最长时间
 * @param {D_Sock_Request} *req 发起等待的请求
 */
void sock_wait_add(D_Sock_Wait *sock_wait, int ms, D_Sock_Request *req)
{
    sock_wait->waiting++;
    req->wait = sock_wait;
    req->wait_ms = ms;
}

/***
 * @description: 等待结构的进入函数入口
 * @Author: Liverpool
 * @Date: 2024-10-05 16:08:37
 * @return {*}
 * @param {D_Sock_Wait} *sock_wait 等待结构的内存地址
 * @param {int} ms 需要等待的最长时间
 */
net_err_t sock_wait_entry(D_Sock_Wait *sock_wait, int ms)
{
    // 等待信号量返回
    if (sys_sem_wait(sock_wait->sem, ms) < 0)
    {
        return NET_ERR_TIMEOUT;
    }
    return sock_wait->err;
}

/***
 * @description: 等待结构的唤醒
 * @Author: Liverpool
 * @Date: 2024-10-05 16:11:32
 * @return {*}
 * @param {D_Sock_Wait} *sock_wait 等待结构的内存地址
 * @param {net_err_t} err 出现的错误
 */
void sock_wait_leave(D_Sock_Wait *sock_wait, net_err_t err)
{
    if (sock_wait->waiting > 0)
    {
        sock_wait->waiting--;
        sys_sem_notify(sock_wait->sem);
        sock_wait->err = err;
    }
}

/***
 * @description: sock等待结构的唤醒
 * @Author: Liverpool
 * @Date: 2024-10-07 22:37:07
 * @return {*}
 * @param {D_Sock} *sock 需要唤醒的sock的内存地址
 * @param {int} type 需要唤醒的等待结构的类型
 * @param {int} err 唤醒的错误
 */
void sock_wakeup(D_Sock *sock, int type, int err)
{
    if (type & SOCK_WAIT_CONNECT)
    {
        sock_wait_leave(sock->conn_wait, err);
    }
    if (type & SOCK_WAIT_WRITE)
    {
        sock_wait_leave(sock->send_wait, err);
    }
    if (type & SOCK_WAIT_READ)
    {
        sock_wait_leave(sock->recv_wait, err);
    }
}

/***
 * @description: 创造socket接口的request请求
 * @Author: Liverpool
 * @Date: 2024-09-18 23:47:50
 * @return {*}
 * @param {_message_func} *msg
 */
net_err_t sock_create_request_in(struct _message_func *msg)
{
    // 定义socket内部结构的创建描述信息表
    static const struct sock_info_t
    {
        int protocol; // 定义缺省协议
        D_Sock *(*create)(int family, int protocol);
    } sock_tbl[] = {
        [SOCK_RAW] = {
            .protocol = IPPROTO_ICMP,
            .create = raw_create,
        }};

    D_Sock_Request *req = (D_Sock_Request *)msg->param;
    D_Sock_Create *params = &req->create;
    x_socket_t *s = socket_alloc();
    if (!s)
    {
        debug_error(Debug_SOCKET, "no socket...");
        return NET_ERR_MEMORY;
    }
    // 对type大小进行检查限制
    if ((params->type < 0) || (params->type >= sizeof(sock_tbl) / sizeof(sock_tbl[0])))
    {
        debug_error(Debug_SOCKET, "create sock failed");
        return NET_ERR_MEMORY;
    }

    // 从socket描述表中获取需要创建的表项所对应的创建函数，然后进行调用
    const struct sock_info_t *info = sock_tbl + params->type;
    if (params->protocol == 0) // 缺省协议的处理
    {
        params->protocol = info->protocol;
    }

    D_Sock *sock = info->create(params->family, params->protocol);
    if (!sock) // sock创建失败
    {
        debug_error(Debug_SOCKET, "create sock failed");
        socket_free(s);
        return NET_ERR_MEMORY;
    }
    s->sock = sock; // 指向新分配的内部结构
    req->sockfd = get_index(s);
    return NET_ERR_OK;
}

/***
 * @description: 数据发送socket接口的request请求
 * @Author: Liverpool
 * @Date: 2024-09-18 23:47:50
 * @return {*}
 * @param {_message_func} *msg
 */
net_err_t sock_sendto_request_in(struct _message_func *msg)
{
    D_Sock_Request *req = (D_Sock_Request *)msg->param;
    // 根据索引得到socket的内存地址
    x_socket_t *s = get_socket(req->sockfd);
    if (!s)
    {
        debug_error(Debug_SOCKET, "param error,sockfd err...");
        return NET_ERR_PARAM;
    }
    D_Sock *sock = s->sock;
    D_Sock_Data *data = &req->data;
    // 调用各个socket结构的发送操作函数，进行数据的发送
    if (!sock->operation->sendto)
    {
        debug_error(Debug_SOCKET, "sendto function not implemented...");
        return NET_ERR_NOT_SUPPORT;
    }
    net_err_t err = sock->operation->sendto(sock, data->buf, data->len, data->flags, data->addr, *(data->addr_len), (ssize_t *)&data->comp_len);
    if (err == NET_ERR_MEED_WAIT) // 程序需要等待
    {
        if (sock->send_wait) // 进行接收等待
        {
            sock_wait_add(sock->send_wait, sock->receive_tms, req);
        }
    }
    return err;
}

/***
 * @description:数据socket接口的接收数据接口的request请求
 * @Author: Liverpool
 * @Date: 2024-10-04 16:00:18
 * @return {*}
 * @param {_message_func} *msg
 */
net_err_t sock_recvfrom_request_in(struct _message_func *msg)
{
    D_Sock_Request *req = (D_Sock_Request *)msg->param;
    // 根据索引得到socket的内存地址
    x_socket_t *s = get_socket(req->sockfd);
    if (!s)
    {
        debug_error(Debug_SOCKET, "param error,sockfd err...");
        return NET_ERR_PARAM;
    }
    D_Sock *sock = s->sock;
    D_Sock_Data *data = &req->data;
    if (!sock->operation->recvfrom)
    {
        debug_error(Debug_SOCKET, "recvfrom function not implemented...");
        return NET_ERR_NOT_SUPPORT;
    }
    net_err_t err = sock->operation->recvfrom(sock, data->buf, data->len, data->flags, data->addr, data->addr_len, (ssize_t *)&data->comp_len);
    if (err == NET_ERR_MEED_WAIT) // 程序需要等待
    {
        if (sock->recv_wait) // 进行接收等待
        {
            sock_wait_add(sock->recv_wait, sock->receive_tms, req);
        }
    }
    return err;
}

/***
 * @description: sock结构通用套接字设置
 * @Author: Liverpool
 * @Date: 2024-10-10 00:26:00
 * @return {*}
 * @param {_sock_t} *sock sock的内存地址
 * @param {int} level 套接字设置的级别
 * @param {int} optname 设置选项的名称
 * @param {void} *optval 设置选项的值
 * @param {int} optlen 设置选项的容量
 */
net_err_t sock_setopt(struct _sock_t *sock, int level, int optname, const void *optval, int optlen)
{
    if (level != SOL_SOCKET)
    {
        debug_error(Debug_SOCKET, "unknown level...");
        return NET_ERR_PARAM;
    }
    switch (optname)
    {
    case SO_RCVTIMEO:
    case SO_SNDTIMEO:
        if (optlen != sizeof(struct x_timeval))
        {
            debug_error(Debug_SOCKET, "time size error...");
            return NET_ERR_PARAM;
        }
        struct x_timeval *time = (struct x_timeval *)optval;
        int time_ms = time->tv_sec * 1000 + time->tv_usec / 1000;
        if (optname == SO_RCVTIMEO)
        {
            sock->receive_tms = time_ms;
            return NET_ERR_OK;
        }
        else if (optname == SO_SNDTIMEO)
        {
            sock->send_tms = time_ms;
            return NET_ERR_OK;
        }
        else
        {
            debug_error(Debug_SOCKET, "optname error...");
            return NET_ERR_PARAM;
        }
        break;
    default:
        break;
    }
    debug_error(Debug_SOCKET, "optname error...");
    return NET_ERR_PARAM;
}

/***
 * @description: 设置socket套接字选项的request请求
 * @Author: Liverpool
 * @Date: 2024-10-09 00:54:52
 * @return {*}
 * @param {_message_func} *msg
 */
net_err_t sock_setsockopt_request_in(struct _message_func *msg)
{
    D_Sock_Request *req = (D_Sock_Request *)msg->param;
    // 根据索引得到socket的内存地址
    x_socket_t *s = get_socket(req->sockfd);
    if (!s)
    {
        debug_error(Debug_SOCKET, "param error,sockfd err...");
        return NET_ERR_PARAM;
    }
    D_Sock *sock = s->sock;
    D_Sock_Opt *opt = &req->opt;
    return sock->operation->setopt(sock, opt->level, opt->optname, opt->optval, opt->len);
}